import re
from django.contrib.auth.hashers import make_password
from rest_framework.serializers import ModelSerializer
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from .utils import get_user_by_account
from rest_framework import serializers
from .models import User
from django_redis import get_redis_connection






class CustomTokenObtainSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)

        # 添加自定义字段
        token['username'] = user.username
        token['user_id'] = user.id

        return token

    def validate(self, attrs):
        data = super().validate(attrs)


        # 将自定义的字段添加到返回数据中
        data['username'] = self.user.username
        data['id'] = self.user.id
        return data


#注册功能的实现
class UserModelSerializer(ModelSerializer):
    #短信验证码 生成随机验证码，不需要保存到数据库中
    sms_code = serializers.CharField(min_length=4,max_length=6,write_only=True,label='验证码')
    token = serializers.CharField(max_length=1024,label='token',read_only=True)
    class Meta:
        model = User
        fields = ['id','username', 'password','mobile','sms_code','token']
        extra_kwargs = {
                'id': {'read_only': True},
                'password': {'write_only': True},
                'username': {'read_only': True}, #具有唯一性
                'mobile': {'write_only': True},
            }

    def validate(self, attrs):
        mobile = attrs.get('mobile')
        sms_code = attrs.get('sms_code')

        if not re.match(r'1[3-9]\d{9}',mobile):
            raise serializers.ValidationError('手机号格式不正确')

        if get_user_by_account(mobile):
            raise serializers.ValidationError('手机号已被注册')

        redis_conn = get_redis_connection('sms_code')
        real_sms_code = redis_conn.get(f'sms_{mobile}')

        if real_sms_code is None:
            raise serializers.ValidationError('验证码已过期')
        #redis中存储的验证码是字节串，需要解码
        if real_sms_code.decode() != sms_code:
            raise serializers.ValidationError({'sms_code': '短信验证码有误！'})

        #验证码需要及时删除防止暴力破解
        redis_conn.delete(f'sms_{mobile}')

        return attrs


    def create(self,validated_data):
        #移除不需要的数据
        validated_data.pop('sms_code')
        raw_psd = validated_data.pop('password')
        validated_data['password'] = make_password(raw_psd)
        #设置默认用户名为手机号
        validated_data['username'] = validated_data.pop('mobile')
        validated_data['mobile'] = validated_data['username']
        #解包方法
        user = User.objects.create(**validated_data)

        #生成token值
        refresh = RefreshToken.for_user(user)
        user.token = str(refresh.access_token)
        return user